unit fMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SaveParams;

type
  TForm1 = class(TForm)
    mmoListaRN: TMemo;
    btnLoadList: TButton;
    btnTesta: TButton;
    mmoResults: TMemo;
    dlgOpen1: TOpenDialog;
    procedure btnLoadListClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnTestaClick(Sender: TObject);
  private
    { Private declarations }
    FRNList : TList;

    SaveParams : TSaveParams;

    procedure LoadIni (Path : string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  uNeuralNetwork, uMatrix, MatrixOperations, FileOperations, Ensemble1, 
  Ensemble2, Math, Ensemble3;

{$R *.dfm}

procedure TForm1.btnLoadListClick(Sender: TObject);
var
  RN : TNeuralNetwork;
  Ix : Integer;

  FSizeInput  : Integer ;
  FSizeLayer1 : Integer ;
  FSizeLayer2 : Integer ;
  FEta        : Double  ;
  FEpoca      : Integer ;
  FMomento    : Double  ;
  FIterations : Integer ;


begin
  dlgOpen1.InitialDir := ExtractFileDir(ParamStr(0));
  if dlgOpen1.Execute then
    begin
      mmoListaRN.Lines.LoadFromFile(dlgOpen1.FileName);
      
    end;

  for Ix := 0 to mmoListaRN.Lines.Count-1 do
    begin
      LoadIni(mmoListaRN.Lines[Ix]);

        FEta            := SaveParams.Eta;
        FEpoca          := SaveParams.Epoca;
        FMomento        := SaveParams.Momento;
        FSizeInput      := SaveParams.SizeInput;
        FSizeLayer1     := SaveParams.SizeLayer1;
        FSizeLayer2     := SaveParams.SizeLayer2;
        FIterations     := SaveParams.MaxIt;

        RN := TNeuralNetwork.Create(FSizeInput, FSizeLayer1, FSizeLayer2, FEta, FMomento);

        RN.CarregaBiasLayer1 ( SaveParams.BiasLayer1 );
        RN.CarregaBiasLayer2 ( SaveParams.BiasLayer2 );
        RN.CarregaWeightsLayer1 ( SaveParams.WLayer1 );
        RN.CarregaWeightsLayer2 ( SaveParams.WLayer2 );

        FRNList.Add(RN);

    
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FRNList := TList.Create;
  SaveParams := TSaveParams.Create;
end;

procedure TForm1.LoadIni(Path: String);
var
  IniFile : TextFile ;
  tmp     : String ;
begin

  AssignFile(IniFile, Path );
  Reset(IniFile);
  ReadLn(IniFile, tmp ) ;
  SaveParams.SizeInput  := StrToInt ( tmp ) ;
  ReadLn(IniFile, tmp  ) ;
  SaveParams.SizeLayer1 := StrToInt ( tmp );
  ReadLn(IniFile, tmp ) ;
  SaveParams.SizeLayer2 := StrToInt ( tmp );

  ReadLn(IniFile, tmp );
  SaveParams.Eta := StrToFloat ( tmp );
  ReadLn(IniFile,  tmp ) ;
  SaveParams.Momento := StrToFloat ( tmp );

  // Epoca
  ReadLn(IniFile,  tmp ) ;
  SaveParams.Epoca := StrToInt(tmp) ;

  ReadLn(IniFile,  SaveParams.BiasLayer1  );
  ReadLn(IniFile,  SaveParams.BiasLayer2  );

  ReadLn(IniFile,  SaveParams.WLayer1  );
  ReadLn(IniFile,  SaveParams.WLayer2  );

  Readln ( IniFile , tmp );
  SaveParams.MaxIt := StrToInt ( tmp );

  CloseFile(IniFile);

end;

procedure TForm1.btnTestaClick(Sender: TObject);
var
  X : TMatrix;

  T : TMatrix;


  i, j, h    : Integer;

  TestFile : TStringList;

  TestNumber : Integer;

  line : string;

  Maior : Double;
  MaiorIx : Integer;

  MatchLine : string;

  RN : TNeuralNetwork;

  ShowCount : Integer;

  Ensemble1 : TEnsemble1;
  Ensemble2 : TEnsemble2;
  Ensemble3 : TEnsemble3;

  Distancia : Double;

begin
  X := TMatrix.Create(400, 1);
  T := TMatrix.Create(9, 1);

  TestFile := TStringList.Create;
  Ensemble1 := TEnsemble1.Create;
  Ensemble2 := TEnsemble2.Create;
  Ensemble3 := TEnsemble3.Create;

  TestFile.LoadFromFile(IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + 'teste\testfile.rni');
  TestNumber := TestFile.Count;

  // RNs
  for i := 0 to FRNList.Count-1 do
    mmoResults.lines.Add('');

  // RN comparacao
  mmoResults.lines.Add('');
  // Ensemble1
  mmoResults.lines.Add('');
  // Ensemble2
  mmoResults.lines.Add('');
  // Ensemble3
  mmoResults.lines.Add('');
  // Letra certa
  mmoResults.lines.Add('');

  mmoResults.Lines.BeginUpdate;
  for i := 0 to TestNumber-1 do
    begin
    
      ShowCount := 0;
      line := TestFile[i];

      Delete(line, Pos('?', line), Length(Line));

      TFileOperator.CSVToVector(line, X);

      line := TestFile[i];

      Delete(line, 1, Pos('?', line));

      TFileOperator.CSVToVector(line, T);

      Ensemble1.ValuesList.Clear;
      Ensemble2.ValuesList.Clear;
      Ensemble3.ValuesList.Clear;

      Distancia := 0;
      for j := 0 to FRNList.Count-1 do
        begin

          RN := TNeuralNetwork(FRNList[j]);
      
          RN.FeedForward ( X , T );

          Maior := -999999;
          MaiorIx := -1;
          for h := 0 to RN.Results.RowCount - 1 do
            begin
              if RN.Results[h,0] > Maior then
                begin
                  Maior := RN.Results[h,0];
                  MaiorIx := h;
                end;
            end;

          for h := 0 to RN.Results.RowCount - 1 do
            begin
              Distancia := Distancia + Abs(RN.Results[h,0] - RN.Results[MaiorIx,0]);
            end;
            
          Ensemble1.ValuesList.Add(FloatToStr(MaiorIx));
          Ensemble2.ValuesList.Values[FloatToStr(Distancia)] := (FloatToStr(MaiorIx));
          Ensemble3.ValuesList.Values[FloatToStr(Distancia)] := (FloatToStr(MaiorIx));

          mmoResults.lines[ShowCount] := mmoResults.lines[ShowCount] + ( IntToStr (MaiorIx + 1) + #9);
          Inc(ShowCount);

        end;

      mmoResults.lines[ShowCount] := mmoResults.lines[ShowCount] + ( IntToStr (Ensemble1.BestByRank + 1) + #9);
      Inc(ShowCount);
      mmoResults.lines[ShowCount] := mmoResults.lines[ShowCount] + ( IntToStr (Ensemble2.BestByDistance + 1) + #9);
      Inc(ShowCount);
      mmoResults.lines[ShowCount] := mmoResults.lines[ShowCount] + ( IntToStr (Ensemble3.BestByWeightedRank + 1) + #9);
      Inc(ShowCount);
      
      for h := 0 to T.RowCount - 1 do
        begin
          if T[h, 0] = 1 then
            begin
              mmoResults.lines[ShowCount] := mmoResults.lines[ShowCount] + ( IntToStr (h + 1) + #9);
              Inc(ShowCount);
              Break;
            end;
        end;

    end;
  mmoResults.Lines.EndUpdate;

end;

end.
